package com.link4a.doms.web.auth;

import java.io.IOException;
import java.util.List;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.context.request.ServletWebRequest;

import com.link4a.doms.web.FilterBeanSupport;
import com.link4a.doms.web.JsonResult;
import com.link4a.doms.web.SessionContext;

public class SessionTimeoutFilter extends FilterBeanSupport {

	private Logger logger = LoggerFactory.getLogger(getClass());
	
	private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();
	@Autowired
	private MappingJackson2HttpMessageConverter jasksonMessageConverter;
	@Autowired
	private StringHttpMessageConverter stringMessageConverter;
	@Autowired
	private SessionContext sessionContext;
	
	private String timeoutPage;

	@Override
	public final void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
		if (sessionContext == null) {
			throw new IllegalArgumentException("Cann't find an instance of " + SessionContext.class.getName());
		}
		
		if (!sessionContext.isSessionAlive()) {
			try {
				List<MediaType> mediaTypes = contentNegotiationManager.resolveMediaTypes(new ServletWebRequest(request));
	
				for (MediaType acceptMediaType : mediaTypes) {
	
					if (MediaType.TEXT_HTML.isCompatibleWith(acceptMediaType) || MediaType.APPLICATION_XHTML_XML.isCompatibleWith(acceptMediaType)) {
	
						response.sendRedirect(request.getServletContext().getContextPath() + timeoutPage);
						return;
	
					} else if (MediaType.APPLICATION_JSON.isCompatibleWith(acceptMediaType)) {
	
						JsonResult jsonResult = new JsonResult(JsonResult.TIMEOUT, "会话超时");
						jasksonMessageConverter.write(jsonResult, MediaType.APPLICATION_JSON, new ServletServerHttpResponse(response));
						return;
	
					} else if (MediaType.TEXT_PLAIN.isCompatibleWith(acceptMediaType) || MediaType.ALL.isCompatibleWith(acceptMediaType)) {
	
						stringMessageConverter.write("会话超时", MediaType.TEXT_PLAIN, new ServletServerHttpResponse(response));
						return;
	
					}
				}
			} catch (HttpMediaTypeNotAcceptableException e1) {
				logger.error("Bad HTTP request, unrecognize media type", e1);
			}
		} else {
			chain.doFilter(request, response);
		}

	}

	public void setTimeoutPage(String timeoutPage) {
		this.timeoutPage = timeoutPage;
	}
}
